package com.seqb.manage.reptile.service.impl;

import com.seqb.common.config.SeqbConfig;
import com.seqb.manage.reptile.service.ReptileVideoService;
import com.seqb.manage.video.dao.VideoDao;
import com.seqb.manage.video.domain.VideoDO;
import com.seqb.utils.AesUtils;
import com.seqb.utils.JsonUtils;
import com.seqb.utils.Md5Utils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.StreamUtils;
import org.springframework.web.client.RestTemplate;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author lilinshen
 * @title 请填写标题
 * @description 请填写相关描述
 * @date 2020/4/30
 */
@Service
public class ReptileVideoServiceImpl implements ReptileVideoService {
    @Autowired
    private VideoDao videoDao;
    @Autowired
    private SeqbConfig seqbConfig;
    @Autowired
    private RestTemplate restTemplate;

    @Override
    public void reptileViode() {
        ThreadPoolExecutor tpe = new ThreadPoolExecutor(2, 20,
                60, TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(4),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.CallerRunsPolicy());

        //视频列表api
        String requestUrl = "http://47.56.88.111:8082/index/videoByTime";
        HttpHeaders headers = new HttpHeaders();
        headers.add("suffix", "624970");
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpMethod httpMethod = HttpMethod.POST;
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("post-data", getVideoListPostData(1, Integer.MAX_VALUE));
        HttpEntity httpEntity = new HttpEntity(JsonUtils.beanToJson(paramsMap), headers);
        ResponseEntity<String> responseEntity = null;
        try {
            responseEntity = restTemplate.exchange(requestUrl, httpMethod, httpEntity, String.class);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        HttpStatus status = responseEntity.getStatusCode();
        List<String> videoIds = null;
        if (status.equals(HttpStatus.OK)) {
            String entityBody = responseEntity.getBody();
            Map<String, Object> entityMap = JsonUtils.jsonToMap(entityBody);
            String data = String.valueOf(entityMap.get("data"));
            String result = AesUtils.decrypt(data);
            videoIds = getVideoId(result);
        }
        if (null == videoIds) {
            return;
        }
        for (int i = 0; i < videoIds.size(); i++) {
            //视频直连api
            requestUrl = "https://alipaydatabase.com/video/getVideoUrl";
            String vid = videoIds.get(i);
            paramsMap = new HashMap<>();
            paramsMap.put("post-data", getVideoItemPostData(Integer.valueOf(vid)));
            httpEntity = new HttpEntity(JsonUtils.beanToJson(paramsMap), headers);
            try {
                responseEntity = restTemplate.exchange(requestUrl, httpMethod, httpEntity, String.class);
            } catch (Exception e) {
                System.out.println(e.getMessage());
                continue;
            }
            if (status.equals(HttpStatus.OK)) {
                String entityBody = responseEntity.getBody();
                Map<String, Object> entityMap = JsonUtils.jsonToMap(entityBody);
                String code = String.valueOf(entityMap.get("code"));
                if (!"0".equals(code)) {
                    continue;
                }
                String data = String.valueOf(entityMap.get("data"));
                String result = AesUtils.decrypt(data);
                String videoUrl = result.substring(result.indexOf("url") + 6, result.lastIndexOf("is_full") - 3);
                if (!StringUtils.isEmpty(videoUrl)) {
                    videoUrl = videoUrl.replaceAll("\\\\", "");
                    //下载视频线程
                    tpe.execute(new DownVideo(vid, videoUrl));
                }
            }
        }

        tpe.shutdown();
    }


    /**
     * 下载视频线程
     */
    class DownVideo implements Runnable {
        String vid;
        String videoUrl;

        public DownVideo(String vid, String videoUrl) {
            this.vid = vid;
            this.videoUrl = videoUrl;
        }

        @Override
        public void run() {
            //下载视频
            File upload = restTemplate.execute(videoUrl, HttpMethod.GET, null, clientHttpResponse -> {
                String filePath = seqbConfig.getUploadPath() + "video/9uu/" + vid + ".m3u8";
                File file = new File(filePath);
                StreamUtils.copy(clientHttpResponse.getBody(), new FileOutputStream(file));
                return file;
            });

            //生成一条记录
            String fileUrl = "/files/video/9uu/" + vid + ".m3u8";
            VideoDO video = new VideoDO();
            video.setType("1");
            video.setFileUrl(fileUrl);
            video.setName("9uu-" + vid);
            video.setFileSize(upload.length());
            videoDao.insert(video);
        }
    }

    private String getVideoListPostData(int pageNumber, int pageSize) {
        //page=1&row_count=20timestamp=1585809942&timezone=GMT+08:00&type=1&6Bf2_kh*P?4tuB*C#@WEVf752x8beCE@uB-Z
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("page=")
                .append(pageNumber)
                .append("&row_count=")
                .append(pageSize)
                .append("&timestamp=1585809942&timezone=GMT+08:00&type=1&6Bf2_kh*P?4tuB*C#@WEVf752x8beCE@uB-Z");
        String encodeSign = stringBuffer.toString();
        Map<String, Object> params = new HashMap<>();
        params.put("type", "1");
        params.put("row_count", pageSize);
        params.put("page", pageNumber);
        params.put("timezone", "GMT+08:00");
        params.put("timestamp", "1585809942");
        params.put("encode_sign", Md5Utils.md5(encodeSign));
        return AesUtils.encrypt(JsonUtils.beanToJson(params));
    }

    private String getVideoItemPostData(int vid) {
        //devicetype=pc&road=default1&timestamp=1585815671868&vid=73160&6Bf2_kh*P?4tuB*C#@WEVf752x8beCE@uB-Z
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("devicetype=pc&road=default1&timestamp=1585815671868&vid=").append(vid).append("&6Bf2_kh*P?4tuB*C#@WEVf752x8beCE@uB-Z");
        String encodeSign = stringBuffer.toString();
        Map<String, Object> params = new HashMap<>();
        params.put("vid", vid);
        params.put("road", "default1");
        params.put("timestamp", "1585815671868");
        params.put("devicetype", "pc");
        params.put("encode_sign", Md5Utils.md5(encodeSign));
        return AesUtils.encrypt(JsonUtils.beanToJson(params));
    }

    private List<String> getVideoId(String parent) {
        List<String> listId = new ArrayList<>();
        String regex = "\"id\":[0-9][0-9]*";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(parent);
        while (matcher.find()) {
            if (!StringUtils.isEmpty(matcher.group().trim())) {
                listId.add(matcher.group().trim().substring(5));
            }
        }
        return listId;
    }

}
